// echo aux function only, should not compile alone.
// -r:"../../Backend/System.IO.FileSystem.dll"

//! 编译方法，目前来说只能是自己改上面那行字，把缺的东西都补齐，之后送命令提示符或者用python脚本编译。
//! windows就是一坨shit……连通配符都不支持……不然我至少能写出类似 dotnet C:\Program Files\dotnet\sdk\*\Roslyn\bincore\csc.dll 这样的语法

// -r:"../../The Scroll of Taiwu_Data/Managed/Mono.Cecil.dll" -r:"../../The Scroll of Taiwu_Data/Managed/System.Core.dll"   -r:"../../The Scroll of Taiwu_Data/Managed/System.Composition.AttributedModel.dll" -r:"../../Backend/System.Runtime.dll"
/**
 *  Everyone's Unity Game Plugin
 *  Copyright (C) 2022 Neutron3529
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
//! 这是一个自带文档注释的Mod，虽然代码很shit，但里面有不少注释，或许会对之后准备玩过月逻辑的人有帮助。
//! 所有文档注释会用//!开头，请注意搜索
//! 首先是前后端，前端对后端的调用会先被塞进 ProcessMethodCall，之后分发给对应domain的CallMethod，由CallMethod进行进一步的分发。借助这一点，我们可以快速找到前端调用究竟是在使用哪个函数。
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using static Utils.Logger;

using Config.EventConfig;
using GameData.Domains.TaiwuEvent;
using GameData.Domains.TaiwuEvent.Enum;

namespace Neutron3529.ChaosEvents {
    public partial class ChaosEvents : EventPackage {
        public 道长.道长 E02(){
            var o=new 道长.道长();
            {
                var taiwuEvent = GameData.Domains.DomainManager.TaiwuEvent.GetEvent("245a7e65-0e12-4fd6-aace-ca57cb5b3b10"); // 遇到入魔人_伤重-使用剑柄-成功
                var lst=taiwuEvent.EventConfig.EventOptions.ToList();
                lst.Insert(0, o.EventOptions[0]);
                taiwuEvent.EventConfig.EventOptions=lst.ToArray();
            }
            {
                var taiwuEvent = GameData.Domains.DomainManager.TaiwuEvent.GetEvent("fb38f657-6ed0-41e4-a0c2-c82afb49762f"); // @人物互动-恩义互动
                var lst=taiwuEvent.EventConfig.EventOptions.ToList();
                for(int i=1;i<o.EventOptions.Length;i++){
                    lst.Insert(lst.Count-1, o.EventOptions[i]);
                }
                taiwuEvent.EventConfig.EventOptions=lst.ToArray();
            }
            return o;
        }
    }
    namespace 道长 {
        public class 道长 : EventContainer {
            public 道长() :base("Prof.道长", "70b4d45d-ba15-423d-b94e-b40e348eb9c2"){
                this.EventOptions = new TaiwuEventOption[4];
                for(int i=0;i<this.EventOptions.Length;i++){
                    var op=new TaiwuEventOption {
                        OptionKey = "Option_3529020"+(i+1).ToString(),
                        OnOptionSelect = new Func<string>(this.OnOptionSelect(i)),
                        OnOptionVisibleCheck = new Func<bool>(this.OnCheckOptionCondition(i)),
                        OnOptionAvailableCheck = new Func<bool>(this.OnCheckEventCondition),
                        GetReplacedContent = new Func<string>(this.Desc(i)),
                        GetExtraFormatLanguageKeys = new Func<List<string>>(this.GetExtraFormatLanguageKeys)
                    };
                    this.EventOptions[i]=op;
                }
            }

            private Func<bool> OnCheckOptionCondition(int i){
                if(i>0){
                    return ()=>{
                        var pd=GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
                        if(pd!=null && pd.TemplateId == 5 && pd.IsSkillUnlocked(1)){
                            var character = this.EventOptions[i].ArgBox.GetCharacter("CharacterId");
                            return character!=null;
                        }
                        return false;
                    };
                } else {
                    return ()=>{
                        var pd=GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
                        var calc=pd!=null
                        && pd.TemplateId == 5
                        && pd.IsSkillUnlocked(2)
                        && pd.GetSkillsData<GameData.Domains.Taiwu.Profession.SkillsData.TaoistMonkSkillsData>().SurvivedTribulationCount<8
                        // && GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetTaiwuInventoryItemCount(12, 234)>=99
                        ;
                        return calc;
                    };
                }
            }
            public static string[] life=new string[]{"音律","弈棋","诗书","绘画","术数","品鉴","锻造","制木","医术","毒术","织锦","巧匠","道法","佛学","厨艺","杂学"};

            static unsafe int 开悟(GameData.Domains.Character.Character targetChar, int add=1, int limit=90){
                var baseLifeSkillQualifications = targetChar.GetBaseLifeSkillQualifications();
                var minIndex=0;
                {
                    var minv=limit;
                    for(var i=0;i<16;i++){
                        if(baseLifeSkillQualifications.Items[i]<minv){
                            minv=baseLifeSkillQualifications.Items[i];
                            minIndex=i;
                        }
                    }
                }
                if(baseLifeSkillQualifications.Items[minIndex]<limit){
                    baseLifeSkillQualifications.Items[minIndex] = (short)Math.Min(limit, baseLifeSkillQualifications.Items[minIndex]+add);
                    targetChar.SetBaseLifeSkillQualifications(ref baseLifeSkillQualifications, GameData.Domains.DomainManager.TaiwuEvent.MainThreadDataContext);
                    return minIndex;
                } else {
                    return -1;
                }
            }

            private unsafe Func<string> OnOptionSelect(int index){
                switch(index){
                    case 0: return ()=> {
                        var ArgBox=this.EventOptions[index].ArgBox;
                        var character = ArgBox.GetCharacter("CharacterId");
                        var RoleTaiwu = ArgBox.GetCharacter("RoleTaiwu");
                        var cname=Name(ArgBox.GetCharacter("CharacterId"));
                        var tname=Name(ArgBox.GetCharacter("RoleTaiwu"));
                        var location = RoleTaiwu.GetLocation();
                        short areaId = location.AreaId;
                        int spiritualDebtChangeByInfected = GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetSpiritualDebtChangeByInfected(character);
                        GameData.Domains.TaiwuEvent.EventHelper.EventHelper.ChangeSpiritualDebtByAreaId(areaId, (short)spiritualDebtChangeByInfected);
                        GameData.Domains.TaiwuEvent.EventHelper.EventHelper.ChangeRoleInfectedValue(character, -200);
                        GameData.Domains.TaiwuEvent.EventHelper.EventHelper.KillCharacter(RoleTaiwu.GetId(), character.GetId(), GameData.Domains.TaiwuEvent.Enum.EKillCharacterType.KillInPublic);
                        int x=GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetTaiwuInventoryItemCount(12, 234);
                        if(x<99){
                            GameData.Domains.TaiwuEvent.EventHelper.EventHelper.AddItemToRole(RoleTaiwu, 12, 234, 99 - x, -1);
                        }
                        return "29104798-3e21-4b86-a0b7-623a4595435b";
                    };
                    case 1: return ()=> {
                        var ArgBox=this.EventOptions[index].ArgBox;
                        var targetChar = ArgBox.GetCharacter("CharacterId");
                        var selfChar = ArgBox.GetCharacter("RoleTaiwu");
                        var cname=Name(targetChar);
                        var tname=Name(selfChar);
                        var location = selfChar.GetLocation();
                        var currDate = GameData.Domains.DomainManager.World.GetCurrDate();
                        int minIndex;
                        if((minIndex=开悟(targetChar))!=-1){
                            GameData.Domains.DomainManager.LifeRecord.GetLifeRecordCollection().AddTaoismAwakeningSucceed(selfChar.GetId(), currDate, targetChar.GetId(), location);
                            return Goto($"道可道，非常道……\n名可名，非常名……\n\n{cname}听{tname}一番讲解，似有什么感悟涌上心头\n<color=#lightgrey>（{cname}的{Grade(life[minIndex],8)}资质提升了）</color>","（喜出望外……）",index);
                        } else {
                            return Goto($"道可道，非常道\n非常道，天之道\n天之道，天知道……\n\n{cname}听{tname}一番讲解，如雾里看花，不明所以","不错不错，小友还是颇具慧根的嘛。哈哈哈……",index);
                        }
                    };
                    case 2: return ()=> {
                        var ArgBox=this.EventOptions[index].ArgBox;
                        var context = GameData.Domains.DomainManager.TaiwuEvent.MainThreadDataContext;
                        var character = ArgBox.GetCharacter("CharacterId");
                        if(character!=null)for(short feature =270; feature<270+7*9;feature+=9){ // 270=窗禽赐啼,最后一个324=鶤鸡赐啼
                            GameData.Domains.TaiwuEvent.EventHelper.EventHelper.AddFeature(character,feature,true);
                        }
                        if(character.CanBeXiangshuInfected()) {
                            GameData.Domains.TaiwuEvent.EventHelper.EventHelper.ChangeRoleInfectedValue(character, 100);
                        }
                        return "69c7acc1-0f57-4004-87fc-5ecf226eb44c"; // 云游道，逆天改命，好结果
                    };
                    case 3: return ()=> {
                        var RoleTaiwu=this.EventOptions[index].ArgBox.GetCharacter("RoleTaiwu");
                        var character=this.EventOptions[index].ArgBox.GetCharacter("CharacterId");
                        var bt=GameData.Domains.DomainManager.Taiwu.GetTaiwu().GetBehaviorType();
                        var blck=GameData.Domains.DomainManager.Map.GetBlock(character.GetLocation());
                        var location = character.GetLocation();
                        var currDate = GameData.Domains.DomainManager.World.GetCurrDate();
                        GameData.Domains.TaiwuEvent.EventHelper.EventHelper.ChangeRoleBehaviorType(character,bt);
                        var affected=0;
                        if(blck!=null && blck.CharacterSet!=null){
                            var cid=character.GetId();
                            var CharacterSet=blck.CharacterSet.Union(GameData.Domains.DomainManager.Taiwu.GetGroupCharIds().GetCollection());
                            foreach(var x in CharacterSet){
                                if(GameData.Domains.DomainManager.Character.TryGetElement_Objects(x, out var ch)){
                                    int cnt=0;
                                    while(开悟(ch, 90)!=-1){
                                        cnt++;
                                        if(cnt>16){
                                            logwarn($"开悟函数出错，令{GameData.Domains.DomainManager.Character.GetNameRelatedData(x).GetMonasticTitleOrDisplayName(false)}(id:{x})开悟了{cnt}次");
                                            break;
                                        }
                                    }
                                    if(cnt!=0){
                                        GameData.Domains.DomainManager.LifeRecord.GetLifeRecordCollection().AddTaoismAwakeningSucceed(RoleTaiwu.GetId(), currDate, x, location);
                                        affected++;
                                    }
                                }
                            }
                        }
                        var tname=Name(RoleTaiwu);
                        return affected>0?Goto($"道可道，非常道……\n名可名，非常名……\n\n<color=#lightgrey>（{tname}的传道极大程度地提升了当地人物的资质水平，共{affected}人资质得到提升）</color>","（意犹未满……）",index):Goto($"道可道，非常道\n非常道，天之道\n天之道，天知道……\n\n{tname}费尽唇舌，也未能将道法讲个明白","（无奈离开……）",index);
                    };
                }
                return ()=>string.Empty;
            }
            public override Func<string> Desc(int i){
                switch(i){
                    case 0:
                        return ()=>"（天劫涤魂，借假修真，引天劫净化此残骸……）";
                    case 1:
                        return ()=>"（道法开悟……）";
                    case 2:
                        return ()=>"（天人赐福，使得受术者被天地（相枢）钟爱，获得所有元鸡的赐啼，但会因此入邪化魔……）";
                    case 3:
                        return ()=>"（开坛讲道……）";
                }
                return ()=>string.Empty;
            }
        }
    }
}
